<template>
  <div id="filter-table">
    <div class="result-wrap">
      <div class="inner" v-show="resultList.length > 0">
        <span v-for="item in resultList" class="result-item">
          {{ item.value }}
          <CloseOutlined @click="remove(item)" />
        </span>
        <span @click="removeAll" class="result-clear">清空条件</span>
      </div>
    </div>

    <a-table
      :data-source="data"
      :columns="columns"
      :pagination="pagination"
      @change="handleTableChange"
      bordered
      :scroll="{ y: props.scrollY }"
    >
      <template #headerCell="{ column }">
        <template v-if="column.key === 'name'">
          <span style="color: #1890ff">Name</span>
        </template>
      </template>
      <template
        #customFilterDropdown="{ setSelectedKeys, selectedKeys, confirm, clearFilters, column }"
      >
        <div class="filter-wrap">
          <div class="filter-item">
            <div class="filter-title">快捷操作</div>
            <div
              @click="
                () => {
                  state[column.key].sort = 'sequ';
                  confirm();
                }
              "
              class="sort sort-sequ"
              :class="[state[column.key].sort == 'sequ' ? 'sort-active' : '']"
            >
              <ArrowUpOutlined />正序排序
            </div>
            <div
              class="sort sort-desc"
              @click="
                () => {
                  state[column.key].sort = 'desc';
                  confirm();
                }
              "
              :class="[state[column.key].sort == 'desc' ? 'sort-active' : '']"
            >
              <ArrowDownOutlined />倒序排序
            </div>
          </div>
          <div class="filter-item">
            <div class="filter-title">添加筛选条件</div>
            <a-input
              v-model:value="state[column.key].searchText"
              @change="handleInputChange(column)"
              size="small"
              class="filter-input"
            >
              <template #prefix>
                <SearchOutlined />
              </template>
            </a-input>
            <a-checkbox
              v-model:checked="state[column.key].checkAll"
              :indeterminate="state[column.key].indeterminate"
              @change="onCheckAllChange(column)"
            >
              全选
            </a-checkbox>
            <div class="filter-checkbox">
              <a-checkbox-group
                :options="state[column.key].options"
                v-model:value="state[column.key].checkedList"
                @change="handleCheckChange(column)"
              />
            </div>
          </div>
          <div class="filter-bth">
            <div class="filter-bth-clear" @click="clearSelect(column)">清空所选内容</div>
            <a-button
              type="primary"
              size="small"
              @click="handleSearch(selectedKeys, confirm, column)"
              >确定</a-button
            >
          </div>
        </div>
      </template>
      <template #customFilterIcon="{ filtered }">
        <FilterOutlined :style="{ color: filtered ? '#108ee9' : undefined }" />
      </template>
    </a-table>
    <a-button type="primary">按钮</a-button>
  </div>
</template>
<script lang="ts" setup>
  import { ref, computed } from 'vue';

  const props = defineProps({
    columns: {
      type: Array,
      default: () => {
        return [];
      },
    },
    tableData: {
      type: Array,
      default: () => {
        return [];
      },
    },
    total: {
      type: Number,
      default: 0,
    },
    scrollY: {
      type: Number,
      default: 300,
    },
  });

  const emits = defineEmits(['getTableData']);
  const data = ref<any>(props.tableData);
  
  const state = ref<any>({});
  const pageSize = ref<number>(10);
  const pagination = computed(() => ({
    total: props.total,
    pageSize: pageSize.value,
  }));

  Object.keys(data.value[0]).forEach((el) => {
    state.value[el] = {};
  });

  const resultList = ref<any>([]);

  const getColumns = (column, searchText: string = '') => {
    //获取筛选的数据选项
    const list: any = [];
    data.value.forEach((el) => {
      if (searchText) {
        if (el[column.key].toUpperCase().includes(searchText.toUpperCase())) {
          list.push({
            label: el[column.key],
            value: el.key,
          });
        }
      } else {
        list.push({
          label: el[column.key],
          value: el.key,
        });
      }
    });

    return list;
  };

  const handleCheckChange = (column) => {
    const options = state.value[column.key].options;
    const isSelectAll = options.length === state.value[column.key].checkedList.length;
    const isSelectNull = state.value[column.key].checkedList.length === 0;
    state.value[column.key].indeterminate = !isSelectNull && !isSelectAll;
    state.value[column.key].checkAll = isSelectAll;
  };

  const onCheckAllChange = (column) => {
    state.value[column.key].indeterminate = false;
    if (state.value[column.key].checkAll) {
      const options = state.value[column.key].options;
      state.value[column.key].checkedList = options.map((el) => el.value);
    } else {
      state.value[column.key].checkedList = [];
    }
  };

  const clearSelect = (column) => {
    state.value[column.key].checkAll = false;
    state.value[column.key].indeterminate = false;
    state.value[column.key].checkedList = [];
  };

  const handleInputChange = (column) => {
    let searchText = state.value[column.key].searchText;
    state.value[column.key].options = getColumns(column, searchText);
  };

  const columns = ref<any>(props.columns);

  columns.value.forEach((el) => {
    if (el.customFilterDropdown) {
      state.value[el.key].options = getColumns(el.key);
    }
  });
  const handleSearch = (selectedKeys, confirm, column) => {
    confirm();
    getResult(column);
  };

  const getResult = (column) => {
    const current = state.value[column.key];
    const checkedList = current.checkedList;
    const options = current.options;
    let result: any = [];
    if (checkedList?.length > 0) {
      options.forEach((el: any) => {
        checkedList.forEach((item) => {
          if (el.value === item) {
            result.push(el.label);
          }
        });
      });
    }
    let isExistedRow = resultList.value.find((el) => el.key == column.key);
    if (checkedList?.length === 0 && isExistedRow) {
      resultList.value = resultList.value.filter((el) => el.key != column.key);
      return;
    }
    const resStr = result.length > 3 ? result.slice(0, 3).join('、') + ' 等' : result.join('、');
    const finalMap = {
      label: column.title,
      key: column.key,
      value: `${column.title} 包含 ${resStr}`,
    };
    if (isExistedRow) {
      isExistedRow.value = finalMap.value;
    } else {
      resultList.value.push(finalMap);
    }
  };
  const remove = (item) => {
    state.value[item.key].checkedList = [];
    state.value[item.key].indeterminate = false;
    resultList.value = resultList.value.filter((v) => v.key !== item.key);
  };

  const removeAll = () => {
    resultList.value.forEach((item) => {
      state.value[item.key].checkedList = [];
      state.value[item.key].indeterminate = false;
    });
    resultList.value = [];
  };

  const handleTableChange = (
    pag: { pageSize: number; current: number },
    filters: any,
    sorter: any,
  ) => {
    emits('getTableData', pag);
  };
</script>
<style lang="less" scoped>
  .filter-wrap {
    width: 240px;
    min-height: 100px;
    padding: 10px;
    box-sizing: border-box;

    .filter-item {
      user-select: none;

      .filter-title {
        font-size: 12px;
        color: #ccc;
        margin-bottom: 10px;
      }

      .sort {
        margin: 10px 0;
        cursor: pointer;
      }

      .filter-input {
        margin-bottom: 10px;
      }

      .filter-checkbox {
        max-height: 180px;
        overflow: auto;

        :deep(.ant-checkbox-group) {
          display: flex;
          flex-direction: column;
        }
      }

      &:nth-child(2) {
        padding: 8px;
        box-sizing: border-box;
        border: 1px solid #ccc;
      }
    }

    .filter-bth {
      display: flex;
      justify-content: space-between;
      align-items: center;
      margin-top: 10px;

      .filter-bth-clear {
        cursor: pointer;

        &:hover {
          color: #209ee4;
        }
      }
    }
  }

  .highlight {
    background-color: rgb(255, 192, 105);
    padding: 0px;
  }

  .sort-active {
    color: #209ee4;
  }

  .result-wrap {
    display: flex;
    flex-wrap: wrap;
    margin-bottom: 10px;
    align-items: center;
    min-height: 30px;
    line-height: 30px;
    background: #fff;
    border-radius: 4px;
    .result-item {
      flex: 1;
      font-size: 12px;
      margin-right: 15px;
      border: 1px solid #ccc;
      padding: 3px 10px;
      border-radius: 4px;
      box-sizing: border-box;
    }

    .result-clear {
      color: #209ee4;
      cursor: pointer;
      font-size: 14px;
    }
  }
</style>
